home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / mac / DirectX SDK / DXSDK / samples / Multimedia / VBSamples / Direct3D / Donuts / donuts.frm next >
Text File  |  2001-10-08  |  38KB  |  1,134 lines

  1. VERSION 5.00
  2. Begin VB.Form frmVBDonuts 
  3.    Caption         =   "VBDonuts"
  4.    ClientHeight    =   4440
  5.    ClientLeft      =   60
  6.    ClientTop       =   345
  7.    ClientWidth     =   5355
  8.    Icon            =   "Donuts.frx":0000
  9.    LinkTopic       =   "Form1"
  10.    ScaleHeight     =   296
  11.    ScaleMode       =   3  'Pixel
  12.    ScaleWidth      =   357
  13.    StartUpPosition =   3  'Windows Default
  14. End
  15. Attribute VB_Name = "frmVBDonuts"
  16. Attribute VB_GlobalNameSpace = False
  17. Attribute VB_Creatable = False
  18. Attribute VB_PredeclaredId = True
  19. Attribute VB_Exposed = False
  20. Option Explicit
  21.  
  22. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  23. '
  24. '  Copyright (C) 1999-2001 Microsoft Corporation.  All Rights Reserved.
  25. '
  26. '  File:       Donuts.frm
  27. '  Content:    This sample shows how 2d can be simulated with Direct3D using
  28. '              transformed and lit vertices.
  29. '
  30. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  31.  
  32. 'Set the constant for full screen operation.
  33. Const FULLSCREENWIDTH = 640
  34. Const FULLSCREENHEIGHT = 480
  35.  
  36. 'Set the number of sprites used in the sample.
  37. Const NUM_SPRITES = 100
  38.  
  39. 'Set the maximum velocity of the sprites.
  40. Const MAX_VELOCITY = 1.5
  41.  
  42. 'Flexible vertex format the describes transformed and lit vertices.
  43. Const FVF = D3DFVF_XYZRHW Or D3DFVF_TEX1 Or D3DFVF_DIFFUSE Or D3DFVF_SPECULAR
  44.  
  45. 'This structure describes a transformed and lit vertex.
  46. Private Type TLVERTEX
  47.     x As Single
  48.     y As Single
  49.     z As Single
  50.     rhw As Single
  51.     color As Long
  52.     specular As Long
  53.     tu As Single
  54.     tv As Single
  55. End Type
  56.  
  57. 'A structure that defines all the needed properties
  58. 'of the Sprite.
  59. Private Type typeSprite
  60.     AnimDimensions As Single        'The dimensions of one frame of animation.
  61.     AnimSpeed As Single             'The speed at which the animation occurs.
  62.     AnimTheta As Single             'The current animation time count.
  63.     FramesPerRow As Long            'How many animation frames are contained in one row in the texture.
  64.     FramesTotal As Long             'Total number of frames for this animation.
  65.     FrameCurrent As Single          'The current animation frame.
  66.     RowOffset As Single             'Offset of the texture start for this sprite.
  67.     SpriteDimensions As Single      'The dimensions of this sprite as will be displayed on the screen in pixels.
  68.     SpriteNum As Long               'The index of this sprite.
  69.     SpriteVerts(3) As TLVERTEX   'Vertex information for this sprite.
  70.     Velocity As D3DVECTOR2          'The velocity of this sprite.
  71.     Location As D3DVECTOR2          'The location of this sprite.
  72. End Type
  73.  
  74. Dim m_Sprite(NUM_SPRITES) As typeSprite
  75.  
  76. 'Dim the DirectX objects/structs the app uses.
  77. Dim dx As DirectX8
  78. Dim d3d As Direct3D8
  79. Dim dev As Direct3DDevice8
  80. Dim d3dx As D3DX8
  81. Dim d3dtBackground As Direct3DTexture8
  82. Dim d3dtSprite As Direct3DTexture8
  83. Dim m_d3dpp As D3DPRESENT_PARAMETERS
  84.  
  85. 'Dim the vertices for the background DirectX logo.
  86. Dim m_MainVerts(3) As TLVERTEX
  87.  
  88. 'Module level boolean that determines whether
  89. 'the app is in fullscreen or windowed.
  90. Dim m_bWindowed As Boolean
  91.  
  92. 'Module level variable to store the caps of the device.
  93. Dim m_D3DCaps As D3DCAPS8
  94.  
  95. 'Module level variable to store the display mode.
  96. Dim m_d3ddm As D3DDISPLAYMODE
  97.  
  98. 'Module level variables to store the window dimensions.
  99. Dim m_lWindowWidth As Long
  100. Dim m_lWindowHeight As Long
  101.  
  102. 'Variables to store the render surface width and height.
  103. Dim m_lClientWidth As Long
  104. Dim m_lClientHeight As Long
  105.  
  106. 'Module level variable to store app state.
  107. Dim m_bRunning As Boolean
  108.  
  109. Private Sub Form_Load()
  110.  
  111.     'Show and size the form.
  112.     With Me
  113.         .Show
  114.         .Height = .ScaleY(300, vbPixels, vbTwips)
  115.         .Width = .ScaleX(400, vbPixels, vbTwips)
  116.     End With
  117.         
  118.     'Seed the random number generator.
  119.     Call Randomize
  120.     
  121.     'Call the sub to initialize the app.
  122.     Call InitApp
  123.         
  124.     'Start the main loop of the sample.
  125.     Call MainLoop
  126.  
  127. End Sub
  128.  
  129. Private Sub InitApp()
  130.  
  131.     '***********************************************************************
  132.     '
  133.     ' This sub initializes the application.
  134.     '
  135.     ' Parameters:
  136.     '
  137.     '           None.
  138.     '
  139.     '***********************************************************************
  140.     
  141.     Dim lErrNum As Long
  142.             
  143.     'Store the current window dimensions
  144.     m_lWindowWidth = Me.ScaleWidth
  145.     m_lWindowHeight = Me.ScaleHeight
  146.     
  147.     'Call the function that initializes the DirectX8, Direct3D8, and Direct3DDevice8 objects.
  148.     lErrNum = InitD3D(dx, d3d, dev, Me.hwnd)
  149.     If lErrNum Then
  150.         'There was an error. We'll need to exit out at this point.
  151.         Unload Me
  152.     End If
  153.     
  154.     'Set the d3dx variable to a new D3DX8 object
  155.     Set d3dx = New D3DX8
  156.     
  157.     'Call the function to load any textures.
  158.     Call InitTextures
  159.     
  160. End Sub
  161.  
  162. Private Sub MainLoop()
  163.     
  164.     '***********************************************************************
  165.     '
  166.     ' This sub is the main loop for the sample.
  167.     '
  168.     ' Parameters:
  169.     '
  170.     '           None.
  171.     '
  172.     '***********************************************************************
  173.                 
  174.     m_bRunning = True
  175.     
  176.     Do While m_bRunning
  177.         
  178.         Call RenderScene
  179.         DoEvents
  180.         
  181.     Loop
  182.                 
  183.     'Exiting app now
  184.     Unload Me
  185.     
  186. End Sub
  187.  
  188. Private Sub RenderScene()
  189.  
  190.     '***********************************************************************
  191.     '
  192.     ' This sub handles the rendering of the scene.
  193.     '
  194.     ' Parameters:
  195.     '
  196.     '   None.
  197.     '
  198.     '***********************************************************************
  199.     
  200.     On Local Error Resume Next
  201.             
  202.     Dim hr As Long
  203.     
  204.     'Call TestCooperativeLevel to see what state the device is in.
  205.     hr = dev.TestCooperativeLevel
  206.     
  207.     If hr = D3DERR_DEVICELOST Then
  208.         
  209.         'If the device is lost, exit and wait for it to come back.
  210.         Exit Sub
  211.     
  212.     ElseIf hr = D3DERR_DEVICENOTRESET Then
  213.             
  214.         'The device became lost for some reason (probably an alt-tab) and now
  215.         'Reset() needs to be called to try and get the device back.
  216.         hr = 0
  217.         hr = ResetDevice()
  218.         
  219.         'If the device failed to be reset, exit the sub.
  220.         If hr Then Exit Sub
  221.     
  222.     End If
  223.     
  224.     'Make sure the app isn't minimized.
  225.     If Me.WindowState <> vbMinimized Then
  226.         
  227.         'The app is ready for rendering.
  228.         With dev
  229.                                     
  230.             'Clear the back buffer
  231.             Call .Clear(0, ByVal 0&, D3DCLEAR_TARGET, &HFF, 0, 0)
  232.             
  233.             'Begin the 3d scene
  234.             Call .BeginScene
  235.             
  236.             'Set the background texture on the device
  237.             Call .SetTexture(0, d3dtBackground)
  238.             
  239.             'Draw the 2 polygons that make up the background
  240.             Call .DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, m_MainVerts(0), Len(m_MainVerts(0)))
  241.             
  242.             'Call the sub that renders the sprites
  243.             Call RenderSprites
  244.             
  245.             'End the scene
  246.             Call .EndScene
  247.             
  248.             'Draw the graphics to the front buffer.
  249.             Call .Present(ByVal 0&, ByVal 0&, 0, ByVal 0&)
  250.             
  251.         End With
  252.     
  253.     End If
  254.     
  255. End Sub
  256.  
  257. Private Sub RenderSprites()
  258.  
  259.     '***********************************************************************
  260.     '
  261.     ' This sub handles the rendering and animation of the sprites.
  262.     '
  263.     ' Parameters:
  264.     '
  265.     '   None.
  266.     '
  267.     '***********************************************************************
  268.     
  269.     Dim i As Long
  270.     Dim TexX As Single, TexY As Single
  271.     
  272.     With dev
  273.         
  274.         'Set the Sprite texture on the device
  275.         Call .SetTexture(0, d3dtSprite)
  276.         
  277.         'Make sure the device supports alpha blending
  278.         If (m_D3DCaps.TextureCaps And D3DPTEXTURECAPS_ALPHA) Then
  279.             
  280.             'It does, so turn alpha blending on
  281.             Call .SetRenderState(D3DRS_ALPHABLENDENABLE, 1)
  282.         
  283.         End If
  284.                                                
  285.        For i = 0 To UBound(m_Sprite)
  286.  
  287.             'Call the sub that updates the Sprite
  288.             Call UpdateSprite(i)
  289.  
  290.             'Draw the 2 polygons that make up the Sprite
  291.             Call .DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, m_Sprite(i).SpriteVerts(0), Len(m_Sprite(i).SpriteVerts(0)))
  292.  
  293.         Next
  294.         
  295.         
  296.         'If alpha blending was turned on
  297.          If .GetRenderState(D3DRS_ALPHABLENDENABLE) Then
  298.             
  299.             'Turn it back off
  300.             Call .SetRenderState(D3DRS_ALPHABLENDENABLE, 0)
  301.             
  302.         End If
  303.         
  304.     End With
  305.     
  306. End Sub
  307.  
  308. Private Sub UpdateSprite(ByVal index As Long)
  309.     
  310.     '***********************************************************************
  311.     '
  312.     ' This sub updates the sprites texture coordinates and position.
  313.     ' Direc3DDevice8.
  314.     '
  315.     ' Parameters:
  316.     '
  317.     ' [IN]
  318.     '       index:      The index of the Sprite to update.
  319.     '
  320.     '***********************************************************************
  321.         
  322.     Dim TexX As Single, TexY As Single
  323.     
  324.     With m_Sprite(index)
  325.                 
  326.         'Update the theta for this sprite.
  327.         .AnimTheta = .AnimTheta + .AnimSpeed
  328.         
  329.         'If the theta count is greater than one, advance the animation frame.
  330.         If .AnimTheta > 1 Then
  331.             
  332.             'Reset theta
  333.             .AnimTheta = 0
  334.             
  335.             'Advance the animation frame
  336.             .FrameCurrent = .FrameCurrent + 1
  337.             If .FrameCurrent >= .FramesTotal Then
  338.                 .FrameCurrent = 0
  339.             End If
  340.             
  341.         End If
  342.         
  343.         'Calculate the updated texture coordinates for this Sprite
  344.         TexY = ((.FrameCurrent \ .FramesPerRow) * .AnimDimensions) + .RowOffset
  345.         TexX = (.FrameCurrent Mod .FramesPerRow) * .AnimDimensions
  346.         
  347.         'Update the position of the Sprite
  348.         .Location.x = .Location.x + .Velocity.x
  349.         .Location.y = .Location.y + .Velocity.y
  350.         
  351.         .SpriteVerts(0).x = .Location.x
  352.         .SpriteVerts(0).y = .Location.y + .SpriteDimensions
  353.         .SpriteVerts(0).tu = TexX
  354.         .SpriteVerts(0).tv = TexY + .AnimDimensions
  355.         
  356.         .SpriteVerts(1).x = .Location.x
  357.         .SpriteVerts(1).y = .Location.y
  358.         .SpriteVerts(1).tu = TexX
  359.         .SpriteVerts(1).tv = TexY
  360.                 
  361.         .SpriteVerts(2).x = .Location.x + .SpriteDimensions
  362.         .SpriteVerts(2).y = .Location.y + .SpriteDimensions
  363.         .SpriteVerts(2).tu = TexX + .AnimDimensions
  364.         .SpriteVerts(2).tv = TexY + .AnimDimensions
  365.         
  366.         .SpriteVerts(3).x = .Location.x + .SpriteDimensions
  367.         .SpriteVerts(3).y = .Location.y
  368.         .SpriteVerts(3).tu = TexX + .AnimDimensions
  369.         .SpriteVerts(3).tv = TexY
  370.         
  371.         'Check to see if the Sprite hit a wall. If it did, reverse its velocity.
  372.         If .Location.x <= 0 Then
  373.             .Velocity.x = -1 * .Velocity.x
  374.         ElseIf .Location.x + .SpriteDimensions >= m_lClientWidth Then
  375.             .Velocity.x = -1 * .Velocity.x
  376.         End If
  377.         
  378.         If .Location.y <= 0 Then
  379.             .Velocity.y = -1 * .Velocity.y
  380.         ElseIf .Location.y + .SpriteDimensions >= m_lClientHeight Then
  381.             .Velocity.y = -1 * .Velocity.y
  382.         End If
  383.  
  384.     End With
  385.  
  386. End Sub
  387.  
  388. Private Function InitD3D(dx As DirectX8, d3d As Direct3D8, dev As Direct3DDevice8, ByVal hwnd As Long, Optional ByVal bWindowed As Boolean = True) As Long
  389.  
  390.     '***********************************************************************
  391.     '
  392.     ' This function creates the following objects: DirectX8, Direct3D8,
  393.     ' Direc3DDevice8.
  394.     '
  395.     ' Parameters:
  396.     '
  397.     ' [IN]
  398.     '       hwnd:       Handle to a window that will be used as the render target
  399.     '       bWindowed:  Optional boolean argument that initializes either full screen
  400.     '                   or windowed. Default is windowed.
  401.     ' [OUT]
  402.     '       dx:         Pass in an uninitialized DirectX8 object.
  403.     '       d3d:        Pass in an uninitialized Direct3D8 object.
  404.     '       dev:        Pass in an uninitialized Direct3DDevice8 object.
  405.     '
  406.     ' Return value:
  407.     '
  408.     '     If an error occurs, it returns the Direct3D error number. In the
  409.     '     case that no fullscreen format was found, it returns D3DERR_INVALIDDEVICE.
  410.     '
  411.     '***********************************************************************
  412.     
  413.     Dim DevType As CONST_D3DDEVTYPE
  414.     Dim i As Long, lCount As Long, lErrNum As Long, format As Long
  415.     Dim bFoundMode As Boolean
  416.         
  417.     'Turn off error checking. The app will check for errors and handle them.
  418.     On Local Error Resume Next
  419.     
  420.     'Store the window mode that was passed in
  421.     m_bWindowed = bWindowed
  422.         
  423.     'Initiazlize the DirectX8 object
  424.     Set dx = New DirectX8
  425.         
  426.     'Check to make sure that the dx object was created successfully.
  427.     If Err.Number Then
  428.     
  429.         'There were problems creating the dx object. Return the error number.
  430.         InitD3D = Err.Number
  431.         Exit Function
  432.         
  433.     End If
  434.     
  435.     'Create the Direct3D object
  436.     Set d3d = dx.Direct3DCreate
  437.     
  438.     'Check to make sure that the d3d object was created successfully.
  439.     If Err.Number Then
  440.     
  441.         'There were problems creating the d3d object. Return the error number,
  442.         InitD3D = Err.Number
  443.         Exit Function
  444.         
  445.     End If
  446.     
  447.     'We'll start by attempting to create a HAL device. This variable
  448.     'will hold the final type of device that we create after we check
  449.     'some capabilities.
  450.     DevType = D3DDEVTYPE_HAL
  451.     
  452.     'Get the capabilities of the Direct3D device that we specify. In this case,
  453.     'we'll be using the adapter default (the primiary card on the system).
  454.     Call d3d.GetDeviceCaps(D3DADAPTER_DEFAULT, DevType, m_D3DCaps)
  455.     
  456.     'Check for errors. If there is an error, the card more than likely doesn't support at least DX7,
  457.     'so get the caps of the reference device instead.
  458.     If Err.Number Then
  459.         
  460.         Err.Clear
  461.         DevType = D3DDEVTYPE_REF
  462.         Call d3d.GetDeviceCaps(D3DADAPTER_DEFAULT, DevType, m_D3DCaps)
  463.         
  464.         'If there is *still* an error, then the driver has problems. We'll
  465.         'have to exit at this point, because there isn't anything else we can
  466.         'do.
  467.         If Err.Number Then
  468.             InitD3D = D3DERR_NOTAVAILABLE
  469.             Exit Function
  470.         End If
  471.         
  472.     End If
  473.     
  474.     'Grab some information about the current display mode.
  475.     Call d3d.GetAdapterDisplayMode(D3DADAPTER_DEFAULT, m_d3ddm)
  476.     
  477.     'Now we'll go ahead and fill the D3DPRESENT_PARAMETERS type.
  478.     With m_d3dpp
  479.         
  480.         If bWindowed Then
  481.                         
  482.             'Make sure that the adapter is in a color bit-depth greater than 8 bits per pixel.
  483.             If m_d3ddm.format = D3DFMT_P8 Or m_d3ddm.format = D3DFMT_A8P8 Then
  484.                 'Device is running in some variation of an 8 bit format
  485.                 MsgBox " For this sample to run, the primary display needs to be in 16 bit or higher color depth.", vbCritical
  486.                 InitD3D = D3DERR_INVALIDDEVICE
  487.                 Exit Function
  488.             Else
  489.                 'Device is greater than 8 bit. Set the format variable to the current display format.
  490.                 format = m_d3ddm.format
  491.             End If
  492.             
  493.             'For windowed mode, we just discard any information instead of flipping it.
  494.             .SwapEffect = D3DSWAPEFFECT_DISCARD
  495.                         
  496.             'Set windowed mode to true.
  497.             .Windowed = 1
  498.                         
  499.         Else
  500.         
  501.             'Call the sub to find the first suitable fullscreen format
  502.             lErrNum = FindMode(FULLSCREENWIDTH, FULLSCREENHEIGHT, format)
  503.             
  504.             'If unable to find a suitable mode, the app will have to exit.
  505.             If lErrNum Then
  506.                 MsgBox " Unable to find a compatible format to run the sample.", vbCritical
  507.                 InitD3D = D3DERR_INVALIDDEVICE
  508.                 Exit Function
  509.             End If
  510.         
  511.             'We need the backbuffer to flip with the front for fullscreen. This
  512.             'flag enables this.
  513.             .SwapEffect = D3DSWAPEFFECT_FLIP
  514.                                     
  515.             'Set the width and height
  516.             .BackBufferWidth = FULLSCREENWIDTH
  517.             .BackBufferHeight = FULLSCREENHEIGHT
  518.             
  519.         End If
  520.         
  521.         'Set the backbuffer format
  522.         .BackBufferFormat = format
  523.  
  524.     End With
  525.     
  526.     'Try to create the device now that we have everything set.
  527.     Set dev = d3d.CreateDevice(D3DADAPTER_DEFAULT, DevType, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, m_d3dpp)
  528.     
  529.     'If the creation above failed, try to create a REF device instead.
  530.     If Err.Number Then
  531.         
  532.         Err.Clear
  533.         Set dev = d3d.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, m_d3dpp)
  534.         
  535.         If Err.Number Then
  536.                     
  537.             'The app still hit an error. Both HAL and REF devices weren't created. The app will have to exit at this point.
  538.             InitD3D = Err.Number
  539.             Exit Function
  540.             
  541.         End If
  542.     End If
  543.     
  544.     'Store the client dimensions
  545.     If m_bWindowed Then
  546.         m_lClientWidth = Me.ScaleWidth
  547.         m_lClientHeight = Me.ScaleHeight
  548.     Else
  549.         m_lClientWidth = FULLSCREENWIDTH
  550.         m_lClientHeight = FULLSCREENHEIGHT
  551.     End If
  552.     
  553.     If InitDevice(dev, hwnd) Then
  554.         
  555.         MsgBox "Unable to initialize the device"
  556.         Unload Me
  557.         
  558.     End If
  559.  
  560. End Function
  561.  
  562. Private Function InitDevice(dev As Direct3DDevice8, hwnd As Long) As Long
  563.  
  564.     '***********************************************************************
  565.     '
  566.     ' This function initializes the device with some renderstates, and also
  567.     ' sets up the viewport, camera, and world.
  568.     '
  569.     ' Parameters:
  570.     '
  571.     ' [IN]
  572.     '       dev:    An existing Direct3DDevice8 object
  573.     '       m_d3dpp:  A filled D3DPRESENT_PARAMETERS type
  574.     '       hwnd:   Handle to the target window
  575.     '
  576.     '
  577.     ' Return value:
  578.     '     If an error occurs, it returns D3DERR_INVALIDCALL.
  579.     '
  580.     '***********************************************************************
  581.  
  582.     'On Local Error Resume Next
  583.     Call InitGeometry
  584.     
  585.     With dev
  586.                 
  587.         'Set the vertex shader to an FVF that contains texture coords,
  588.         'and transformed and lit vertex coords.
  589.         Call .SetVertexShader(FVF)
  590.         
  591.         'Turn off lighting
  592.         Call .SetRenderState(D3DRS_LIGHTING, 0)
  593.                                 
  594.         'Set the render state that uses the alpha component as the source for blending.
  595.         Call .SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA)
  596.         
  597.         'Set the render state that uses the inverse alpha component as the destination blend.
  598.         Call .SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA)
  599.         
  600.     End With
  601.         
  602.     If Err.Number Then InitDevice = D3DERR_INVALIDCALL
  603.     
  604. End Function
  605.  
  606. Private Sub InitGeometry()
  607.  
  608.     '***********************************************************************
  609.     '
  610.     ' This sub initializes the vertices for all the needed polygons.
  611.     '
  612.     ' Parameters:
  613.     '           None.
  614.     '
  615.     '***********************************************************************
  616.         
  617.     Dim sDimensions As Single
  618.     Dim i As Long
  619.     Static bInit As Boolean
  620.     
  621.     ' All the polygons that this sample use are made of two triangles that create a rectangle.
  622.     ' The textures are painted on these two polygons to create the look of a 2d sprite.
  623.     ' All of the polygons are transformed and lit, meaning that Direct3D will perform no
  624.     ' lighting calculations, and no coordinate transformation. The application is responsible
  625.     ' for doing all of these calculations. Since this is just a 2d simulation, it's very easy
  626.     ' to set up the polygons and transform them manually.
  627.     ' This illustration shows the placement of each vertex (vn) to draw the rectangle. Notice the
  628.     ' order that the vertices are placed. This follows the clockwise winding order rule for culling
  629.     ' polygons. If the order was reversed, the polygon wouldn't be rendered by Direct3D. See the "3-D
  630.     ' Coordinate Systems and Geometry" section in the docs for more info.
  631.     
  632.     ' * v1      * v3
  633.     ' |\        |
  634.     ' |  \      |
  635.     ' |    \    |
  636.     ' |      \  |
  637.     ' |        \|
  638.     ' * v0      * v2
  639.     
  640.     'Initialize the 2 polygons that will display the DirectX logo
  641.     With m_MainVerts(0)
  642.         
  643.         'X and Y are the familiar XY values in screen space that this vertex will be placed.
  644.         'This one is going in the bottom left corner of the screen.
  645.         .x = 0: .y = m_lClientHeight
  646.         
  647.         'This sets up the texture coordinates for this vertex in the polygon.
  648.         'tu is the X of the texture, tv is the Y of the texture. Texture coordinates
  649.         'are from 0 to 1, 0 being all the way to the left or top, and 1 being all the
  650.         'way to the right or bottom, depending on whether it is the tu or tv element.
  651.         .tu = 0: .tv = 1
  652.         
  653.         'rhw is the value that D3D uses to produce scaling. Since this app
  654.         'won't be doing any scaling, this value needs to be 1.
  655.         .rhw = 1
  656.         
  657.         'Since the app will handle all lighting, the color value will be used
  658.         'to light the polygon. For this app, the polygon will be fully lit.
  659.         .color = &HFFFFFF
  660.     End With
  661.     
  662.     'The rest of the vertices follow the same format, but are placed in different XY coordinates.
  663.     
  664.     With m_MainVerts(1)
  665.         .x = 0: .y = 0
  666.         .tu = 0: .tv = 0
  667.         .rhw = 1
  668.         .color = &HFFFFFF
  669.     End With
  670.     With m_MainVerts(2)
  671.         .x = m_lClientWidth: .y = m_lClientHeight
  672.         .tu = 1: .tv = 1
  673.         .rhw = 1
  674.         .color = &HFFFFFF
  675.     End With
  676.     With m_MainVerts(3)
  677.         .x = m_lClientWidth: .y = 0
  678.         .tu = 1: .tv = 0
  679.         .rhw = 1
  680.         .color = &HFFFFFF
  681.     End With
  682.  
  683.     For i = 0 To UBound(m_Sprite)
  684.                 
  685.         With m_Sprite(i)
  686.                     
  687.             'If this is the first time the sub is called.
  688.             If Not bInit Then
  689.             
  690.                 'Choose a random Sprite
  691.                 .SpriteNum = Int((3) * Rnd)
  692.                                         
  693.                 'Set the sprites properties accordingly
  694.                 If .SpriteNum = 0 Then
  695.                     .FramesPerRow = 8
  696.                     .FramesTotal = 29
  697.                     .RowOffset = 0
  698.                     .AnimDimensions = 0.125
  699.                     .SpriteDimensions = 40
  700.                 ElseIf .SpriteNum = 1 Then
  701.                     .FramesPerRow = 16
  702.                     .FramesTotal = 39
  703.                     .RowOffset = 0.5
  704.                     .AnimDimensions = 0.0625
  705.                     .SpriteDimensions = 15
  706.                 ElseIf .SpriteNum = 2 Then
  707.                     .FramesPerRow = 16
  708.                     .FramesTotal = 39
  709.                     .RowOffset = 0.6875
  710.                     .AnimDimensions = 0.0625
  711.                     .SpriteDimensions = 15
  712.                 End If
  713.             
  714.                 'Choose a random starting location, velocity, and animation frame
  715.                 .Location.x = (m_lClientWidth - .SpriteDimensions) * Rnd
  716.                 .Location.y = (m_lClientHeight - .SpriteDimensions) * Rnd
  717.                 .Velocity.x = (((MAX_VELOCITY - -MAX_VELOCITY) * Rnd) + -MAX_VELOCITY)
  718.                 .Velocity.y = (((MAX_VELOCITY - -MAX_VELOCITY) * Rnd) + -MAX_VELOCITY)
  719.                 .FrameCurrent = Int(.FramesTotal * Rnd)
  720.                 
  721.                 'Calculate the speed at which the animation should occurr. Based on the velocity of the sprite.
  722.                 'The higher the velocity, the faster the animation.
  723.                 .AnimSpeed = ((Abs(.Velocity.x) + Abs(.Velocity.y)) / 4)
  724.                                 
  725.             Else
  726.                 
  727.                 'The window was resized. Make sure sprites are still in view, move them so they are if neccessary.
  728.                 If .Location.x + .SpriteDimensions > m_lClientWidth Then
  729.                     .Location.x = m_lClientWidth - .SpriteDimensions - 1
  730.                 End If
  731.                 
  732.                 If .Location.y + .SpriteDimensions > m_lClientHeight Then
  733.                     .Location.y = m_lClientHeight - .SpriteDimensions - 1
  734.                 End If
  735.                                 
  736.             End If
  737.             
  738.             'Create the vertices for the Sprite
  739.             With .SpriteVerts(0)
  740.                 .x = 0: .y = 0
  741.                 .tu = 0: .tv = m_Sprite(i).AnimDimensions
  742.                 .rhw = 1
  743.                 .color = &HFFFFFF
  744.             End With
  745.             With .SpriteVerts(1)
  746.                 .x = 0: .y = m_Sprite(i).SpriteDimensions
  747.                 .tu = 0: .tv = 0
  748.                 .rhw = 1
  749.                 .color = &HFFFFFF
  750.             End With
  751.             With .SpriteVerts(2)
  752.                 .x = m_Sprite(i).SpriteDimensions: .y = 0
  753.                 .tu = m_Sprite(i).AnimDimensions: .tv = m_Sprite(i).AnimDimensions
  754.                 .rhw = 1
  755.                 .color = &HFFFFFF
  756.             End With
  757.             With .SpriteVerts(3)
  758.                 .x = m_Sprite(i).SpriteDimensions: .y = m_Sprite(i).SpriteDimensions
  759.                 .tu = m_Sprite(i).AnimDimensions: .tv = 0
  760.                 .rhw = 1
  761.                 .color = &HFFFFFF
  762.             End With
  763.             
  764.         End With
  765.         
  766.     Next
  767.     
  768.     'The geometry is initialized. No need to randomize again.
  769.     bInit = True
  770.     
  771. End Sub
  772.  
  773. Private Sub InitTextures()
  774.     
  775.     '***********************************************************************
  776.     '
  777.     ' This sub loads any textures needed. If for some reason this sub doesn't
  778.     ' succeed, we'll just exit the app, because it won't run without the
  779.     ' textures being loaded.
  780.     '
  781.     ' Parameters:
  782.     '           None.
  783.     '
  784.     '***********************************************************************
  785.     
  786.     On Local Error Resume Next
  787.         
  788.     Dim sFile As String
  789.     
  790.     'Locate the path to the media
  791.     sFile = FindMediaDir("dx5_logo.bmp")
  792.     If sFile = "" Then
  793.         sFile = App.Path & "\" & "dx5_logo.bmp"
  794.     Else
  795.         sFile = sFile & "dx5_logo.bmp"
  796.     End If
  797.     
  798.     'Check to make sure the media was found
  799.     If Dir(sFile) = vbNullString Then
  800.         MsgBox "Unable to locate sample media."
  801.         Unload Me
  802.     End If
  803.     
  804.     'Load the background texture
  805.     Set d3dtBackground = d3dx.CreateTextureFromFile(dev, sFile)
  806.         
  807.     'Locate the path to the next media file.
  808.     sFile = FindMediaDir("donuts1.bmp")
  809.     If sFile = "" Then
  810.         sFile = App.Path & "\" & "donuts1.bmp"
  811.     Else
  812.         sFile = sFile & "donuts1.bmp"
  813.     End If
  814.     
  815.     'Check to make sure the media was found
  816.     If Dir(sFile) = vbNullString Then
  817.         MsgBox "Unable to locate sample media."
  818.         Unload Me
  819.     End If
  820.  
  821.     
  822.     'Load the Sprite texture. We need to get alpha information embedded into this
  823.     'surface, so we'll call the more complex CreateTextureFromFileEx() method instead.
  824.     'The main thing we need to do is just let it know we want to use black as the
  825.     'alpha channel. We do this by passing &HFF000000 to the method, and it fills in
  826.     'the high order byte of any pixel that contains black with full alpha so that it
  827.     'becomes transparent when rendered with alpha blending enabled.
  828.     
  829.     Set d3dtSprite = d3dx.CreateTextureFromFileEx( _
  830.                                                     dev, _
  831.                                                     sFile, _
  832.                                                     D3DX_DEFAULT, _
  833.                                                     D3DX_DEFAULT, _
  834.                                                     D3DX_DEFAULT, _
  835.                                                     0, _
  836.                                                     D3DFMT_UNKNOWN, _
  837.                                                     D3DPOOL_MANAGED, _
  838.                                                     D3DX_FILTER_POINT, _
  839.                                                     D3DX_FILTER_POINT, _
  840.                                                     &HFF000000, _
  841.                                                     ByVal 0, _
  842.                                                     ByVal 0 _
  843.                                                     )
  844.             
  845.     If Err.Number Then
  846.         
  847.         'Something happened while loading the texture.
  848.         MsgBox "Error loading texture. Error number: " & Err.Number
  849.         Unload Me
  850.         
  851.     End If
  852.     
  853. End Sub
  854.  
  855. Private Sub SwitchWindowMode()
  856.  
  857.     '***********************************************************************
  858.     '
  859.     ' This sub switches the current display mode between windowed/fullscreen.
  860.     ' If it runs into an error, it just exits, leaving the display mode in
  861.     ' its current state.
  862.     '
  863.     ' Parameters:
  864.     '           None.
  865.     '
  866.     '***********************************************************************
  867.     
  868.     Dim d3dppEmpty As D3DPRESENT_PARAMETERS
  869.     Dim format As Long
  870.     Dim lErrNum As Long
  871.     
  872.     On Local Error Resume Next
  873.     
  874.     If m_bWindowed Then
  875.                                     
  876.         'Grab a valid format for this device. If a format
  877.         'for the requested resolution wasn't found, exit the sub.
  878.         If FindMode(FULLSCREENWIDTH, FULLSCREENHEIGHT, format) <> 0 Then Exit Sub
  879.                 
  880.         'Store the current window mode format
  881.         Call d3d.GetAdapterDisplayMode(D3DADAPTER_DEFAULT, m_d3ddm)
  882.         
  883.         'The app is running windowed currently, switch to fullscreen.
  884.         m_bWindowed = False
  885.                 
  886.         'Set the present parameters for running full screen
  887.         m_d3dpp = d3dppEmpty
  888.         
  889.         With m_d3dpp
  890.             .SwapEffect = D3DSWAPEFFECT_FLIP
  891.             .BackBufferFormat = format
  892.             .BackBufferWidth = FULLSCREENWIDTH
  893.             .BackBufferHeight = FULLSCREENHEIGHT
  894.             .Windowed = 0
  895.         End With
  896.         
  897.         'Store the client dimensions
  898.         m_lClientWidth = FULLSCREENWIDTH
  899.         m_lClientHeight = FULLSCREENHEIGHT
  900.         
  901.         'Reset the device to the new mode
  902.         lErrNum = ResetDevice
  903.         
  904.         'If there is an error resetting the device,
  905.         'just exit the sub.
  906.         If lErrNum Then
  907.             'Store the client dimensions
  908.             m_lClientWidth = Me.ScaleWidth
  909.             m_lClientHeight = Me.ScaleHeight
  910.             m_bWindowed = True
  911.             Exit Sub
  912.         End If
  913.                 
  914.     Else
  915.                                                                                                     
  916.         'Set the present params to reflect windowed operation.
  917.         m_d3dpp = d3dppEmpty
  918.         
  919.         With m_d3dpp
  920.             .SwapEffect = D3DSWAPEFFECT_DISCARD
  921.             .BackBufferFormat = m_d3ddm.format
  922.             .Windowed = 1
  923.         End With
  924.         
  925.         'Reset the device to the new mode
  926.         lErrNum = ResetDevice
  927.         
  928.         'If there is an error, just exit the sub
  929.         If lErrNum Then
  930.             m_bWindowed = False
  931.             Exit Sub
  932.         End If
  933.           
  934.         'Now get the device ready again
  935.         Call InitDevice(dev, Me.hwnd)
  936.               
  937.         'Resize the form to the size it was previous to going fullscreen.
  938.         Me.Width = m_lWindowWidth * Screen.TwipsPerPixelX
  939.         Me.Height = m_lWindowHeight * Screen.TwipsPerPixelY
  940.         
  941.         'The app is now running windowed
  942.         m_bWindowed = True
  943.         
  944.         'Store the client dimensions
  945.         m_lClientWidth = Me.ScaleWidth
  946.         m_lClientHeight = Me.ScaleHeight
  947.         
  948.         'Resize the window to the old size now.
  949.         Call Form_Resize
  950.         
  951.     End If
  952.     
  953. End Sub
  954.  
  955. Private Sub ResizeWindow()
  956.  
  957.     '***********************************************************************
  958.     '
  959.     ' This subroutine is called whenever the form is resized. It resets the
  960.     ' device to the new size, and re-inits the device.
  961.     '
  962.     ' Parameters:
  963.     '
  964.     '   None.
  965.     '
  966.     '***********************************************************************
  967.     
  968.     Dim d3dppEmpty As D3DPRESENT_PARAMETERS
  969.             
  970.     m_lWindowWidth = Me.ScaleWidth
  971.     m_lWindowHeight = Me.ScaleHeight
  972.     m_lClientWidth = m_lWindowWidth
  973.     m_lClientHeight = m_lWindowHeight
  974.     
  975.     'Reset the device to the new mode
  976.     Call ResetDevice
  977.     
  978. End Sub
  979.  
  980. Private Function ResetDevice() As Long
  981.  
  982.     '***********************************************************************
  983.     '
  984.     ' This subroutine is called whenever the app needs to be resized, or the
  985.     ' device has been lost.
  986.     '
  987.     ' Parameters:
  988.     '
  989.     '   None.
  990.     '
  991.     '***********************************************************************
  992.         
  993.     On Local Error Resume Next
  994.     
  995.     Call dev.Reset(m_d3dpp)
  996.     
  997.     If Err.Number Then
  998.         ResetDevice = Err.Number
  999.         Exit Function
  1000.     End If
  1001.     
  1002.     'Now get the device ready again
  1003.     Call InitDevice(dev, Me.hwnd)
  1004.  
  1005. End Function
  1006. Private Function FindMode(ByVal w As Long, ByVal h As Long, fmt As Long) As Long
  1007.     
  1008.     '***********************************************************************
  1009.     '
  1010.     ' This function returns a valid back buffer format for the width and height passed in.
  1011.     '
  1012.     ' Parameters:
  1013.     '
  1014.     ' [IN]
  1015.     '      w is the width of the mode being sought
  1016.     '      h is the height of the mode being sought
  1017.     '
  1018.     ' [OUT]
  1019.     '     fmt will be filled in with a valid CONST_D3DFORMAT
  1020.     '
  1021.     ' Return value:
  1022.     '     If a valid format was not found, D3DERR_INVALIDDEVICE is returned.
  1023.     '     If an error occurs, it returns D3DERR_INVALIDCALL.
  1024.     '***********************************************************************
  1025.     
  1026.     
  1027.     Dim i  As Long, lCount As Long
  1028.     Dim d3ddm As D3DDISPLAYMODE
  1029.     Dim bFoundMode As Boolean
  1030.     
  1031.     i = 0
  1032.     
  1033.     'Get the number of adapter modes this adapter supports.
  1034.     lCount = d3d.GetAdapterModeCount(D3DADAPTER_DEFAULT) - 1
  1035.     
  1036.     'If we encounter an error, return an error code and exit the function.
  1037.     If Err.Number Then
  1038.         FindMode = D3DERR_INVALIDCALL
  1039.         Exit Function
  1040.     End If
  1041.     
  1042.     'Next, loop through all the display modes until we find one
  1043.     'that matches the parameters passed in.
  1044.     For i = 0 To lCount
  1045.         
  1046.         Call d3d.EnumAdapterModes(D3DADAPTER_DEFAULT, i, d3ddm)
  1047.         
  1048.         'Again, catch any unexpected errors.
  1049.         If Err.Number Then
  1050.             FindMode = Err.Number
  1051.             Exit Function
  1052.         End If
  1053.         
  1054.         'Check to see if this mode matches what is being sought.
  1055.         If d3ddm.Width = w And d3ddm.Height = h Then
  1056.             
  1057.             'Now see if this mode is either a 32bpp or 16bpp mode
  1058.             If d3ddm.format = D3DFMT_R8G8B8 Or _
  1059.                 d3ddm.format = D3DFMT_R5G6B5 Then
  1060.                 
  1061.                 'We've found a suitable display. Set the flag
  1062.                 'to reflect this, and exit. No need to look further.
  1063.                 bFoundMode = True
  1064.                 
  1065.                 'Set the fmt to the format that was found.
  1066.                 fmt = d3ddm.format
  1067.                 
  1068.                 Exit For
  1069.             End If
  1070.         End If
  1071.     Next
  1072.         
  1073.     If bFoundMode Then
  1074.         
  1075.         'Everything checked out OK
  1076.         Exit Function
  1077.         
  1078.     Else
  1079.         
  1080.         'Return an error
  1081.         FindMode = D3DERR_INVALIDDEVICE
  1082.         
  1083.     End If
  1084.     
  1085. End Function
  1086.  
  1087. Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
  1088.     
  1089.     If (Shift And vbAltMask) And KeyCode = vbKeyReturn Then
  1090.         
  1091.         'User wants to switch from fullscreen/windowed mode
  1092.         Call SwitchWindowMode
  1093.             
  1094.     ElseIf KeyCode = vbKeyEscape Then
  1095.         
  1096.         'User wants to exit the app
  1097.         m_bRunning = False
  1098.         
  1099.     End If
  1100.                         
  1101. End Sub
  1102.  
  1103. Private Sub Form_Resize()
  1104.  
  1105.     'Call the subroutine that resizes the backbuffer on the device.
  1106.     'Make sure the device exists, and the app is windowed.
  1107.     If Not dev Is Nothing And m_bWindowed Then
  1108.         
  1109.     'Make sure the app isn't minimized.
  1110.     If Me.WindowState <> vbMinimized Then
  1111.         
  1112.         'Make sure the app isn't resized to the point where the sprites could get stuck.
  1113.         If Me.ScaleHeight < 100 Or Me.ScaleWidth < 100 Then
  1114.             Me.Width = Screen.TwipsPerPixelX * 100
  1115.             Me.Height = Screen.TwipsPerPixelY * 100
  1116.         End If
  1117.         
  1118.             Call ResizeWindow
  1119.         End If
  1120.         
  1121.     End If
  1122.     
  1123. End Sub
  1124.  
  1125. Private Sub Form_Unload(Cancel As Integer)
  1126.     
  1127.     'We need to terminate the app using the End statement,
  1128.     'otherwise the form will reload since the app is running
  1129.     'in a loop with DoEvents.
  1130.     End
  1131.     
  1132. End Sub
  1133.  
  1134.